package com.easylinkin.linkappapi.security.config;

import com.easylinkin.bases.redis.util.RedisUtil;
import com.easylinkin.linkappapi.operatelog.entity.CommonOperateLog;
import com.easylinkin.linkappapi.operatelog.service.CommonOperateLogService;
import com.easylinkin.linkappapi.security.entity.LinkappUser;
import com.easylinkin.linkappapi.security.entity.LinkappUserLoginInfo;
import com.easylinkin.linkappapi.security.service.LinkappUserLoginInfoService;
import com.easylinkin.linkappapi.security.service.LinkappUserService;
import com.easylinkin.sm.constant.LogConstant.Module;
import com.easylinkin.sm.entity.Log;
import com.easylinkin.sm.service.LogService;
import java.util.Date;
import java.util.Objects;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.stereotype.Component;
import site.morn.boot.web.Responses;
import site.morn.rest.RestBuilders;
import site.morn.rest.RestMessage;

/**
 * 认证失败处理者
 *
 * @author timely-rain
 * @since 1.2.0, 2019/8/29
 */
@Component
public class LinkappRestAuthenticationFailureHandler implements AuthenticationFailureHandler {

    @Autowired
    private LinkappUserLoginInfoService userLoginInfoService;
    @Autowired
    private LinkappUserService userService;
    @Autowired
    private LogService logService;
    @Autowired
    private RedisUtil redisUtil;
    @Resource
    private LoginCountCheck loginCountCheck;
    @Resource
    private CommonOperateLogService commonOperateLogService;

    @Override
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
        AuthenticationException exception) {

        LinkappUser user = null;
        String username = request.getParameter("username");
        String ssoToken = request.getParameter("ssoToken");
        String phone = request.getParameter("phone");
        String content = "登录失败";
        if (ssoToken == null || ssoToken.length() == 0) {
            if (phone == null || phone.length() == 0) {
                user = userService.findByUsername(username);
                content = "账号" + content;
            } else {
                user = (LinkappUser) redisUtil.get(phone + "_login");
                request.setAttribute("username", user.getUsername());
                content = "短信" + content;
            }
        } else {
            user = (LinkappUser) redisUtil.get(ssoToken);
            request.setAttribute("username", user.getUsername());
        }

        if (user != null && user.getUsername() != null) {
            loginCountCheck.afterLoginHandler(false, user.getUsername());
        }

        CommonOperateLog commonOperateLog = new CommonOperateLog();
        if (user != null) {
            commonOperateLog.setTenantId(user.getTenantId());
            commonOperateLog.setPhone(user.getPhone());
            commonOperateLog.setUserAccount(user.getUsername());
            commonOperateLog.setNickname(user.getNickname());
        }
        String platform = request.getHeader("platform");
        if(StringUtils.isNotEmpty(platform)){
            commonOperateLog.setPlatform(platform);
        }
        commonOperateLog.setModuleName("登录");
        commonOperateLog.setContent(content);
        commonOperateLog.setCreateTime(new Date()).setResult(false);
        commonOperateLogService.addLog(commonOperateLog);

        RestMessage message = RestBuilders.failureBuilder().code("login.failure")
            .message(exception.getMessage()).build();

        Responses.standard(response).respond(message);

    }

    /**
     * 记录登录日志
     *
     * @param request 请求
     * @param user 用户
     * @param responseMessage 响应消息
     */
    private void saveLog(HttpServletRequest request, LinkappUser user, String responseMessage) {
        Log log = new Log();
        log.setModuleId(Long.parseLong(Module.LOGIN));
        log.setIp(request.getRemoteAddr());
        log.setContent("用户登录");
        log.setStatus(false);
        log.setDisplay(true);
        log.setResponseInformation(responseMessage);
        logService.add(log);
    }

    /**
     * 记录登录次数
     *
     * @param user 用户
     */
    private void saveLoginInfo(LinkappUser user) {
        LinkappUserLoginInfo userLoginInfo = userLoginInfoService.get(user.getId());

        if (Objects.nonNull(userLoginInfo)) {
            userLoginInfoService.addErrorCount(user.getId());
        } else {
            //第一次登陆错误
            userLoginInfo = new LinkappUserLoginInfo();
            userLoginInfo.setUserId(user.getId());
            userLoginInfo.setErrorTime(new Date());
            userLoginInfo.setErrorCount(1);
            userLoginInfoService.add(userLoginInfo);
        }
    }
}
